"use strict";
(function (exports) {
    const createCandidates = (adaptor, { cursor, delimiter }) => {
        const escapeRegExp = (aString) => aString.replace(/([!$()*+./:=?[\\\]^{|}])/g, "\\$1");
        const head = (aList) => aList[0];
        const tail = (aList) => aList.slice(1, Infinity);
        const adaptorName = adaptor.name;
        return {
            get data() {
                const re = new RegExp(escapeRegExp(cursor), "i");
                const candidateWord = adaptor.imeConnect.candidateWord;
                const data = candidateWord.replace(re, "").split(delimiter).slice(0, -1);
                const shouldSkipKeystroke = (data) => "Kika" !== adaptorName && /^\d+$/.test(head(data));
                return shouldSkipKeystroke(data) ? tail(data) : data;
            },
            get index() {
                const candidateWord = adaptor.imeConnect.candidateWord;
                return candidateWord.split(delimiter).findIndex((candidate) => {
                    return candidate.startsWith(cursor);
                });
            },
        };
    };
    const createRootCandidates = (adaptor, { cursor, delimiter, separator }) => {
        const escapeRegExp = (aString) => aString.replace(/([!$()*+./:=?[\\\]^{|}])/g, "\\$1");
        return {
            get data() {
                const re = new RegExp(escapeRegExp(cursor), "i");
                const candidateWord = adaptor.imeConnect.candidateWord;
                const data = candidateWord.split(separator)[0].replace(re, "").split(delimiter);
                return data.length === 1 && data[0] === "" ? [] : data;
            },
            get index() {
                const candidateWord = adaptor.imeConnect.candidateWord;
                const roots = candidateWord.split(separator)[0];
                return roots.split(delimiter).findIndex((candidate) => {
                    return candidate.startsWith(cursor);
                });
            },
        };
    };
    const createLeafCandidates = (adaptor, { cursor, delimiter, separator }) => {
        const escapeRegExp = (aString) => aString.replace(/([!$()*+./:=?[\\\]^{|}])/g, "\\$1");
        return {
            get data() {
                const re = new RegExp(escapeRegExp(cursor), "i");
                const candidateWord = adaptor.imeConnect.candidateWord;
                const raw = candidateWord.split(separator)[1];
                const data = raw ? raw.replace(re, "").split(delimiter).slice(0, -1) : [];
                return data;
            },
            get index() {
                const candidateWord = adaptor.imeConnect.candidateWord;
                const roots = candidateWord.split(separator)[1];
                return roots.split(delimiter).findIndex((candidate) => {
                    return candidate.startsWith(cursor);
                });
            },
        };
    };
    const createMyCandidates = (adaptor, { cursor, delimiter, separator }) => {
        return {
            get data() {
                const candidateWord = adaptor.imeConnect.candidateWord;
                // console.log(candidateWord);

                let a = [];
                let b = [];
                let index = -1;

                if (candidateWord.includes(separator)) {
                    const sp = candidateWord.split(separator);
                    a = sp[0].split(delimiter);
                    b = sp[1].split(delimiter).slice(0, -1);
                } else {
                    b = candidateWord.split(delimiter).slice(0, -1);
                }

                for (let i = 0; i < a.length; i++) {
                    if (a[i].startsWith(cursor)) {
                        a[i] = a[i].substring(cursor.length);
                        index = i;
                        break;
                    }
                }

                const data = {
                    a, b, index,
                }
                return data;
            },
        };
    };
    const withKika = (adaptor) => {
        const getLanguageId = (language) => {
            const lang = "english" === language ? "english_us" : language;
            const kikaLangMap = {
                "9key": {
                    english_us: 0x0101,
                    french_ca: 0x0102,
                    portugese_br: 0x0103,
                    spanish_us: 0x0104,
                    bengali: 0x0106,
                    hindi: 0x010a,
                    tamil: 0x0117,
                    telugu: 0x0118,
                    urdu: 0x0119,
                    afrikaans: 0x011a,
                    arabic: 0x011b,
                    chinese_cn: 0x011c,
                    dutch: 0x011d,
                    english_gb: 0x011e,
                    french_fr: 0x011f,
                    german: 0x0120,
                    hungarian: 0x0121,
                    indonesian: 0x0122,
                    italian: 0x0123,
                    malay: 0x0124,
                    persian: 0x0125,
                    polish: 0x0126,
                    portugese_pt: 0x0127,
                    romanian: 0x0128,
                    russian: 0x0129,
                    spanish_es: 0x012a,
                    swahili: 0x012b,
                    thai: 0x012c,
                    turkish: 0x012d,
                    vietnamese: 0x012e,
                    zulu: 0x012f,
                    bengali_bd: 0x0130,
                    bulgarian: 0x0131,
                    croatian: 0x0132,
                    czech: 0x0133,
                    finnish: 0x0134,
                    greek: 0x0135,
                    kazakh: 0x0136,
                    khmer: 0x0137,
                    macedonian: 0x0138,
                    serbian: 0x0139,
                    sinhala: 0x013a,
                    slovak: 0x013b,
                    slovenian: 0x013c,
                    swedish: 0x013d,
                    tagalog: 0x013e,
                    ukrainian: 0x013f,
                    xhosa: 0x0140,
                    albanian: 0x0141,
                    armenian: 0x0142,
                    azerbaijani: 0x0143,
                    belarusian: 0x0144,
                    bosnian: 0x0145,
                    chinese_hk: 0x0146,
                    chinese_tw: 0x0147,
                    danish: 0x0148,
                    estonian: 0x0149,
                    georgian: 0x014a,
                    hebrew: 0x014b,
                    icelandic: 0x014c,
                    lao: 0x014d,
                    latvian: 0x014e,
                    lithuanian: 0x014f,
                    norwegian: 0x0150,
                    uzbek_cyrillic: 0x0151,
                    korean: 0x0156,
                    basque: 0x0152,
                    galician: 0x0153,
                    catalan: 0x0157,
                },
                qwerty: { english_us: 0x0201, french_ca: 0x0202, french_fr: 0x021f, spanish_us: 0x0204, spanish_es: 0x022a },
            };
            const langMap = kikaLangMap[adaptor.layout];
            return langMap[lang] || langMap.english_us;
        };
        const cursor = adaptor.cursor;
        const delimiter = "|";
        const separator = "||";
        return Object.assign({}, adaptor, {
            get candidates() {
                return createCandidates(adaptor, { cursor, delimiter });
            },
            get rootCandidates() {
                return createRootCandidates(adaptor, { cursor, delimiter, separator });
            },
            get leafCandidates() {
                return createLeafCandidates(adaptor, { cursor, delimiter, separator });
            },
            get myCandidates() {
                return createMyCandidates(adaptor, { cursor, delimiter, separator });
            },
            getNextWordCandidates: (word) => {
                return adaptor.imeConnect.getNextWordCandidates(word).split(delimiter).slice(0, -1);
            },
            getCombinedText: (combination) => {
                return adaptor.imeConnect.getComposingWords(combination, 0);
            },
            importDictionary: (blob) => {
                adaptor.imeConnect.importDictionary(blob);
            },
            delimiter,
            getLanguageId,
            pagination: false,
        });
    };
    const withT9 = (adaptor) => {
        const getLanguageId = (language) => {
            const langMap = { english: 0x0b09, french: 0x0c0c, spanish: 0x080a };
            return langMap[language] || langMap.english;
        };
        const cursor = adaptor.cursor;
        const delimiter = adaptor.delimiter;
        return Object.assign({}, adaptor, {
            get candidates() {
                return createCandidates(adaptor, { cursor, delimiter });
            },
            getLanguageId,
            pagination: true,
        });
    };
    const withR9 = (adaptor) => {
        const getLanguageId = (language) => {
            const languages = ["hindi", "assamese", "bengali", "gujarati", "marathi", "telugu", "tamil", "malayalam", "punjabi", "odia", "kannada", "urdu", "kashmiri", "english", "nepali", "konkani", "maithili", "dogri", "sindhi", "sanskrit", "manipuri", "bodo", "santali"];
            return languages.indexOf(language);
        };
        const cursor = adaptor.cursor;
        const delimiter = adaptor.delimiter;
        return Object.assign({}, adaptor, {
            get candidates() {
                return createCandidates(adaptor, { cursor, delimiter });
            },
            getLanguageId,
            pagination: true,
        });
    };
    const withDumb = (adaptor) => {
        return Object.assign({}, adaptor, {
            get candidates() {
                return {
                    get data() {
                        return [" "];
                    },
                    get index() {
                        return 0;
                    },
                };
            },
            pagination: false,
        });
    };
    const dumbConnect = function () {
        return { name: "DUMB", setLetter: () => { }, initEmptyWord: () => { }, cursorPosition: () => { }, setLanguage: () => { }, setLetterMultiTap: () => { }, candidateWord: () => { } };
    };
    const withHuangji = (adaptor) => {
        const cursor = adaptor.cursor;
        const delimiter = "|";
        const separator = "||";
        return Object.assign({}, adaptor, {
            get myCandidates() {
                return createMyCandidates(adaptor, { cursor, delimiter, separator });
            },
            getNextWordCandidates: (word) => {
                return adaptor.imeConnect.getNextWordCandidates(word).split(delimiter).slice(0, -1);
            },
            getCombinedText: (combination) => {
                return adaptor.imeConnect.getComposingWords(combination, 0);
            },
            importDictionary: (blob) => {
                adaptor.imeConnect.importDictionary(blob);
            },
            delimiter,
            pagination: false,
        });
    };
    const createAdaptor = (layout) => {
        // const imeConnect = new (exports.IMEConnect ? exports.IMEConnect : exports.Xt9Connect ? exports.Xt9Connect : dumbConnect)();
        const imeConnect = new exports.HuangjiIMEConnect();
        const name = imeConnect.name;
        const cursor = ">";
        const delimiter = " ";
        const reset = () => {
            imeConnect.setLetter(0, KeyboardEvent.DOM_VK_RETURN);
            imeConnect.initEmptyWord = true;
            imeConnect.cursorPosition = 0;
        };
        const getLanguageId = (_language) => 0;
        const setLanguage = function (name) {
            const languageId = this.getLanguageId(name);
            return imeConnect.setLanguage(languageId);
        };
        const setLetter = (prefix, char) => {
            imeConnect.setLetter(prefix, char);
        };
        const setLetterMultiTap = (code, tapCount, lastCharCode) => {
            imeConnect.setLetterMultiTap(code, tapCount, lastCharCode);
        };
        return { imeConnect, name, cursor, delimiter, layout, reset, getLanguageId, setLanguage, setLetter, setLetterMultiTap };
    };
    const createInstance = (adaptor) => {
        const adaptorName = adaptor.name;
        if ("Huangji" === adaptorName) {
            return withHuangji(adaptor);
        }
        if ("Kika" === adaptorName) {
            return withKika(adaptor);
        }
        if ("XT9" === adaptorName || exports.Xt9Connect) {
            return withT9(adaptor);
        }
        if ("RT9" === adaptorName) {
            return withR9(adaptor);
        }
        return withDumb(adaptor);
    };
    exports.IMEConnectSDK = {
        init: function (layout) {
            if (!this._instance) {
                const adaptor = createAdaptor(layout);
                this._instance = createInstance(adaptor);
            }
        },
        get adaptor() {
            if (!this._instance) {
                const err = new ReferenceError("IMEConnect adaptor is uninitialized.");
                console.error(err);
                throw err;
            }
            return this._instance;
        },
    };
})(window);
